package main

import (
	"fmt"
	"os/exec"
	"strings"
	"time"
	"bytes"
)

// 执行命令并获取输出
func executeCmd(cmd *exec.Cmd, cmdName string) (string, error) {
	var out bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &out

	// 启动命令并等待完成
	err := cmd.Run()
	if err != nil {
		return "", fmt.Errorf("%s 执行失败: %v", cmdName, err)
	}
	return out.String(), nil
}

// 清理 hwclock 输出中的时间部分，去掉多余内容和时区标识符
func cleanHwclockOutput(hwclockOutput string) (string, error) {
	// 修剪多余空格
	cleanedOutput := strings.TrimSpace(hwclockOutput)

	// 找到年份，动态获取当前年份
	currentYear := time.Now().Year()

	// 找到年份位置
	yearIndex := strings.LastIndex(cleanedOutput, fmt.Sprintf(" %d", currentYear)) // 使用当前年份来进行动态查找
	if yearIndex == -1 {
		return "", fmt.Errorf("无法找到年份位置")
	}

	// 截取年份之前的部分，包括年份
	cleanedOutput = cleanedOutput[:yearIndex+5]

	fmt.Println("截取年份之前的部分，包括年份 当前系统时间:", cleanedOutput)

	// 去除时区标识符：例如 " CST" 或 " UTC"，这些通常在年份后
	// 确保去掉所有多余的内容
	// spaceIndex := strings.LastIndex(cleanedOutput, " ")
	// if spaceIndex != -1 && len(cleanedOutput[spaceIndex:]) > 1 {
	// 	cleanedOutput = cleanedOutput[:spaceIndex]
	// }

	// 返回清理后的时间字符串
	return cleanedOutput, nil
}

// 解析时间字符串为 time.Time 类型
func parseHwclockOutput(hwclockOutput string) (time.Time, error) {
	// 使用 Go 的 time.Parse 函数来解析时间字符串
	layout := "Mon Jan 2 15:04:05 2006" // 时间格式
	return time.Parse(layout, hwclockOutput)
}

// 获取硬件时钟时间
func getHwclockTime() (time.Time, error) {
	// 执行 hwclock -l 命令获取硬件时钟时间
	hwclockOutput, err := executeCmd(exec.Command("hwclock", "-l"), "获取本地硬件时间 hwclock")
	if err != nil {
		return time.Time{}, fmt.Errorf("hwclock 无法获取硬件时钟时间: %w", err)
	}

	// 清理 hwclock 时间字符串
	cleanedTime, err := cleanHwclockOutput(hwclockOutput)
	if err != nil {
		return time.Time{}, fmt.Errorf("hwclock 清理硬件时钟时间失败: %w", err)
	}

	// 解析时间字符串
	hwclockTime, err := parseHwclockOutput(cleanedTime)
	if err != nil {
		return time.Time{}, fmt.Errorf("解析硬件时钟时间失败: %w", err)
	}

	return hwclockTime, nil
}

func main() {
	// 获取硬件时钟时间
	hwclockTime, err := getHwclockTime()
	if err != nil {
		fmt.Println("获取硬件时钟时间失败:", err)
		return
	}

	// 获取当前系统时间
	systemTime := time.Now()

	// 输出硬件时钟时间与系统时间
	fmt.Println("硬件时钟时间:", hwclockTime)
	fmt.Println("当前系统时间:", systemTime)

	// 计算硬件时钟时间与系统时间的差值
	timeDifference := systemTime.Sub(hwclockTime)

	fmt.Println("系统时间 与 硬件时间相差 =", timeDifference)
	// 比较硬件时钟与系统时间
	if hwclockTime.Before(systemTime) {
		fmt.Println("硬件时钟时间较早")
	} else if hwclockTime.After(systemTime) {
		fmt.Println("硬件时钟时间较晚")
	} else {
		fmt.Println("硬件时钟与系统时间一致")
	}
}
